home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / cvs-1_3.lha / cvs-1.3 / src / release.c < prev    next >
C/C++ Source or Header  |  1992-02-29  |  5KB  |  220 lines

  1. /*
  2.  * Release: "cancel" a checkout in the history log.
  3.  * 
  4.  * - Don't allow release if anything is active - Don't allow release if not
  5.  * above or inside repository. - Don't allow release if ./CVS/Repository is
  6.  * not the same as the directory specified in the module database.
  7.  * 
  8.  * - Enter a line in the history log indicating the "release". - If asked to,
  9.  * delete the local working directory.
  10.  */
  11.  
  12. #include "cvs.h"
  13.  
  14. #ifndef lint
  15. static char rcsid[] = "@(#)release.c 1.21 92/02/29";
  16. #endif
  17.  
  18. #if __STDC__
  19. static void release_delete (char *dir);
  20. #else
  21. static void release_delete ();
  22. #endif                /* __STDC__ */
  23.  
  24. static char *release_usage[] =
  25. {
  26.     "Usage: %s %s [-d] modules...\n",
  27.     "\t-Q\tReally quiet.\n",
  28.     "\t-d\tDelete the given directory.\n",
  29.     "\t-q\tSomewhat quiet.\n",
  30.     NULL
  31. };
  32.  
  33. static short delete;
  34.  
  35. int
  36. release (argc, argv)
  37.     int argc;
  38.     char **argv;
  39. {
  40.     FILE *fp;
  41.     register int i, c;
  42.     register char *cp;
  43.     int margc;
  44.     DBM *db;
  45.     datum key, val;
  46.     char *repository, *srepos;
  47.     char **margv, *modargv[MAXFILEPERDIR], line[PATH_MAX];
  48.  
  49.     if (argc == -1)
  50.     usage (release_usage);
  51.     optind = 1;
  52.     while ((c = gnu_getopt (argc, argv, "Qdq")) != -1)
  53.     {
  54.     switch (c)
  55.     {
  56.         case 'Q':
  57.         really_quiet = 1;
  58.         /* FALL THROUGH */
  59.         case 'q':
  60.         quiet = 1;
  61.         break;
  62.         case 'd':
  63.         delete++;
  64.         break;
  65.         case '?':
  66.         default:
  67.         usage (release_usage);
  68.         break;
  69.     }
  70.     }
  71.     argc -= optind;
  72.     argv += optind;
  73.  
  74.     if (!(db = open_module ()))
  75.     return (1);
  76.     for (i = 0; i < argc; i++)
  77.     {
  78.  
  79.     /*
  80.      * If we are in a repository, do it.  Else if we are in the parent of
  81.      * a directory with the same name as the module, "cd" into it and
  82.      * look for a repository there.
  83.      */
  84.     if (isdir (argv[i]))
  85.     {
  86.         if (chdir (argv[i]) < 0)
  87.         {
  88.         if (!really_quiet)
  89.             error (0, 0, "can't chdir to: %s", argv[i]);
  90.         continue;
  91.         }
  92.         if (!isdir (CVSADM) && !isdir (OCVSADM))
  93.         {
  94.         if (!really_quiet)
  95.             error (0, 0, "no repository module: %s", argv[i]);
  96.         continue;
  97.         }
  98.     }
  99.     else
  100.     {
  101.         if (!really_quiet)
  102.         error (0, 0, "no such directory/module: %s", argv[i]);
  103.         continue;
  104.     }
  105.  
  106.     repository = Name_Repository ((char *) NULL, (char *) NULL);
  107.     srepos = Short_Repository (repository);
  108.  
  109.     /* grab module entry from database and check against short repos */
  110.     key.dptr = argv[i];
  111.     key.dsize = strlen (key.dptr);
  112.     val = dbm_fetch (db, key);
  113.     if (!val.dptr)
  114.     {
  115.         error (0, 0, "no such module name: %s", argv[i]);
  116.         continue;
  117.     }
  118.     val.dptr[val.dsize] = '\0';
  119.     if ((cp = index (val.dptr, '#')) != NULL) /* Strip out a comment */
  120.     {
  121.         do
  122.         {
  123.         *cp-- = '\0';
  124.         } while (isspace (*cp));
  125.     }
  126.     (void) sprintf (line, "%s %s", key.dptr, val.dptr);
  127.     line2argv (&margc, modargv, line);
  128.     margv = modargv;
  129.  
  130.     optind = 1;
  131.     while (gnu_getopt (margc, margv, CVSMODULE_OPTS) != -1)
  132.          /* do nothing */ ;
  133.     margc -= optind;
  134.     margv += optind;
  135.  
  136.     if (margc < 1)
  137.     {
  138.         error (0, 0, "modules file missing directory for key %s value %s",
  139.            key.dptr, val.dptr);
  140.         continue;
  141.     }
  142.     if (strcmp (*margv, srepos))
  143.     {
  144.         error (0, 0, "repository mismatch: module[%s], here[%s]",
  145.            *margv, srepos);
  146.         free (repository);
  147.         continue;
  148.     }
  149.  
  150.     if (!really_quiet)
  151.     {
  152.  
  153.         /*
  154.          * Now see if there is any reason not to allow a "Release" This
  155.          * is "popen()" instead of "Popen()" since we don't want "-n" to
  156.          * stop it.
  157.          */
  158.         fp = popen ("cvs -n -q update", "r");
  159.         c = 0;
  160.         while (fgets (line, sizeof (line), fp))
  161.         {
  162.         if (index ("MARCZ", *line))
  163.             c++;
  164.         (void) printf (line);
  165.         }
  166.         (void) pclose (fp);
  167.         (void) printf ("You have [%d] altered files in this repository.\n",
  168.                c);
  169.         (void) printf ("Are you sure you want to release %smodule `%s': ",
  170.                delete ? "(and delete) " : "", argv[i]);
  171.         c = !yesno ();
  172.         if (c)            /* "No" */
  173.         {
  174.         (void) fprintf (stderr, "** `%s' aborted by user choice.\n",
  175.                 command_name);
  176.         free (repository);
  177.         continue;
  178.         }
  179.     }
  180.  
  181.     /*
  182.      * So, we've passed all the tests, go ahead and release it. First,
  183.      * log the release, then attempt to delete it.
  184.      */
  185.     history_write ('F', argv[i], "", argv[i], "");    /* F == Free */
  186.     free (repository);
  187.  
  188.     if (delete)
  189.         release_delete (argv[i]);
  190.     }
  191.     close_module (db);
  192.     return (0);
  193. }
  194.  
  195. /* We want to "rm -r" the repository, but let us be a little paranoid. */
  196. static void
  197. release_delete (dir)
  198.     char *dir;
  199. {
  200.     struct stat st;
  201.     ino_t ino;
  202.     int retcode = 0;
  203.  
  204.     (void) stat (".", &st);
  205.     ino = st.st_ino;
  206.     (void) chdir ("..");
  207.     (void) stat (dir, &st);
  208.     if (ino != st.st_ino)
  209.     {
  210.     error (0, 0,
  211.            "Parent dir on a different disk, delete of %s aborted", dir);
  212.     return;
  213.     }
  214.     run_setup ("%s -r", RM);
  215.     run_arg (dir);
  216.     if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL)) != 0)
  217.     error (0, retcode == -1 ? errno : 0, 
  218.            "deletion of module %s failed.", dir);
  219. }
  220.